﻿#include "UICombobox.h"
#include "UIButton.h"
#include "UIScrollPanel.h"
#include "../../Input/Mouse.h"

UICombobox::UICombobox()
{
	Width = 180;
	Height = 30;

	SetDefaultOptions();
}

UICombobox::UICombobox(float xPos, float yPos)
{
	Position = Point{ xPos, yPos };
	Width = 180;
	Height = 30;

	SetDefaultOptions();
}

UICombobox::UICombobox(float xPos, float yPos, float width, float height)
{
	Position = Point{ xPos, yPos };
	Width = width;
	Height = height;

	SetDefaultOptions();
}

void UICombobox::AddItem(std::string item)
{
	m_Items.push_back(item);
	UIButton* item_btn = new UIButton(0, 0, 0, 0, item);
	item_btn->AddLeftMouseClickEvent([this](UIElement* sender) {
		if (m_ShouldDrawItems)
		{
			m_ShouldDrawItems = false;

			int old_index = m_SelectedIndex;
			int new_index = m_ItemScrollPanel->IndexOf(sender);
			m_SelectedIndex = new_index;

			if (new_index != old_index)
				for (selecte_index_changed_evt cb : m_SelectedIndexChangedEvents)
					cb(this, new_index);
		}
	});
	m_ItemScrollPanel->AddElement(item_btn);
}

void UICombobox::ClearItems()
{
	m_ItemScrollPanel->RemoveAllElements();
	m_Items.clear();
	m_SelectedIndex = 0;
}

void UICombobox::RemoveItem(int index)
{
	if (m_Items.size() < 1 || index < 0 || index >= (int)m_Items.size()) return;

	m_ItemScrollPanel->RemoveElement(index);
	m_Items.erase(m_Items.begin() + index);
	m_SelectedIndex = 0;
}

void UICombobox::RemoveItem(std::string item)
{
	int idx = IndexOf(item);
	if (idx != -1)
		RemoveItem(idx);
}

void UICombobox::SetSelectedIndex(int index)
{
	int old_index = m_SelectedIndex;
	m_SelectedIndex = index;

	if (index != old_index)
		for (selecte_index_changed_evt cb : m_SelectedIndexChangedEvents)
			cb(this, index);
}

int UICombobox::IndexOf(std::string item)
{
	for (size_t i = 0; i < m_Items.size(); i++)
		if (item._Equal(m_Items.at(i)))
			return (int)i;
	return -1;
}

void UICombobox::SetDefaultOptions()
{
	m_ItemScrollPanel = std::unique_ptr<UIScrollPanel>(new UIScrollPanel());
	m_ItemScrollPanel->Height = 70;

	AddEnterFocusEvent([this](UIElement* sender) {
		m_ShouldDrawItems = true;
	});

	AddLeaveFocusEvent([this](UIElement* sender) {
		bool mouse_in_dropdown_area = Mouse::IsMouseCursorInsideRect(SourceWindow, Position.x, Position.y, Width, Height + m_ItemScrollPanel->Height); // is mouse inside the total area of combobox and drop down item menu area
		
		if (mouse_in_dropdown_area) Focus(); // keep the combobox focus if the mouse is clicked outside of it but inside the drop down menu area

		if (m_ShouldDrawItems && !mouse_in_dropdown_area) // if the mouse is clicked completely outside the combobox and drop down menu area
			m_ShouldDrawItems = false;
	});
}

void __stdcall UICombobox::Draw(Graphics* graphics)
{
	// Drawing the frame
	if (!RoundedCorners)
		graphics->DrawRectangle(Position.x, Position.y, Width, Height, color.r, color.g, color.b, color.a, 0, true);
	else
		graphics->DrawRoundedRectangle(Position.x, Position.y, Width, Height, RoundCornerRadiusX, RoundCornerRadiusY, color.r, color.g, color.b, color.a, 0, true);

	// Drawing the drop-down arrow
	graphics->drawText(L"▼", "Arial", 14, FONT_STYLE_NORMAL, FONT_WEIGHT_NORMAL, Position.x + Width - 14.0f, Position.y, 10.0f, Height - 0.6f,
		ArrowColor.r, ArrowColor.g, ArrowColor.b, ArrowColor.a, DWRITE_TEXT_ALIGNMENT_CENTER, DWRITE_PARAGRAPH_ALIGNMENT_CENTER);

	if (m_Items.size() < 1) return; // No Items to draw

	if (m_SelectedIndex < 0 || m_SelectedIndex >= (int)m_Items.size()) m_SelectedIndex = 0;

	// Drawing the selected item text
	graphics->drawText(m_Items.at(m_SelectedIndex), FontName, FontSize, FontStyle, FontWeight, Position.x + 2.0f, Position.y, Width - 10.0f, Height,
		TextColor.r, TextColor.g, TextColor.b, TextColor.a, DWRITE_TEXT_ALIGNMENT_CENTER, DWRITE_PARAGRAPH_ALIGNMENT_CENTER);

	if (m_Items.size() < 2) return; // If there is only one item there is no need to draw the item panel

	m_ItemScrollPanel->Position.x = Position.x;
	m_ItemScrollPanel->Position.y = Position.y + Height;
	m_ItemScrollPanel->Width = Width;
	m_ItemScrollPanel->_get_scrollbar_handle_()->Position.x = Position.x + Width - m_ItemScrollPanel->_get_scrollbar_handle_()->Width;
	m_ItemScrollPanel->SlotWidth = m_ItemScrollPanel->Width - m_ItemScrollPanel->ScrollbarWidth;

	if (m_ShouldDrawItems)
	{
		m_ItemScrollPanel->Draw(graphics);
	}
}
